package com.qf.fmall2203.shiro;

import cn.hutool.jwt.JWT;
import com.qf.fmall2203.utils.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

//@Component("jwt")
@Slf4j
public class JwtShiroFilter extends AccessControlFilter {

    /**
     * 返回 true， 请求可以继续向下执行 ; 返回 false，请求会被 onAccessDenied 方法处理
     * @param request
     * @param response
     * @param mappedValue
     * @return
     * @throws Exception
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {

        HttpServletRequest req = (HttpServletRequest) request;

        // 从请求头中获取 token
        final String token = req.getHeader("token");

        // 如果请求头中没有携带 token，则直接拒绝该请求
        if (token == null || "".equals(token)){
            log.debug("没有携带token");
            return false;
        }

        // 校验token 的合法性
        final boolean validate = JWT.of(token).setKey(Constants.SECRET.getBytes("utf-8"))
                .validate(0);

        if (validate){
            // token 合法，放行
            log.debug("token 校验通过");
            return true;
        }else {
            // token 非法
            log.debug("token 校验失败");
            return false;
        }


    }

    /**
     * 当上面的方法返回 false时，会进入如下方法
     * 该方法返回true，请求依然会继续向下执行，如果返回false，则请求不向下执行
     * 在JWT校验场景下 推荐 返回false
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

        //提示 token校验失败
        response.getWriter().println("token not ok");
        log.debug("token not ok");
        // 让请求就此打住
        return false;
    }
}
